001 /* 002 * Copyright 2004 Stephen J. McConnell. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 013 * implied. 014 * 015 * See the License for the specific language governing permissions and 016 * limitations under the License. 017 */ 018 019 package net.dpml.metro.data; 020 021 import java.util.Arrays; 022 023 import net.dpml.component.Directive; 024 025 import net.dpml.metro.info.PartReference; 026 027 /** 028 * A context descriptor declares the context creation criteria for 029 * the context instance and context entries. 030 * 031 * <p><b>XML</b></p> 032 * <p>A context directive may contain multiple import statements. Each import 033 * statement corresponds to a request for a context value from the container.</p> 034 * <pre> 035 * <context class="<font color="darkred">MyContextClass</font>"> 036 * <entry key="<font color="darkred">special</font>"> 037 * <import key="<font color="darkred">urn:avalon:classloader</font>"/> 038 * </entry> 039 * <entry key="<font color="darkred">xxx</font>"> 040 * <param class="<font color="darkred">MySpecialClass</font>"> 041 * <param><font color="darkred">hello</font></param> 042 * <param class="<font color="darkred">java.io.File</font>"><font color="darkred">../lib</font></param> 043 * </param> 044 * </entry> 045 * </context> 046 * </pre> 047 * 048 * @author <a href="http://www.dpml.net">Digital Product Meta Library</a> 049 * @version 1.0.1 050 */ 051 public final class ContextDirective extends AbstractDirective 052 { 053 //-------------------------------------------------------------------------- 054 // static 055 //-------------------------------------------------------------------------- 056 057 /** 058 * Serial version identifier. 059 */ 060 static final long serialVersionUID = 1L; 061 062 private static final PartReference[] EMPTY_REFS = new PartReference[0]; 063 064 //-------------------------------------------------------------------------- 065 // state 066 //-------------------------------------------------------------------------- 067 068 /** 069 * The set of entry directives. 070 */ 071 private final PartReference[] m_entries; 072 073 /** 074 * The context implementation classname. 075 */ 076 private final String m_classname; 077 078 //-------------------------------------------------------------------------- 079 // constructors 080 //-------------------------------------------------------------------------- 081 082 /** 083 * Creation of a context directive. 084 */ 085 public ContextDirective() 086 { 087 this( new PartReference[0] ); 088 } 089 090 /** 091 * Creation of a context directive 092 * @param entries the set of entry descriptors 093 */ 094 public ContextDirective( final PartReference[] entries ) 095 { 096 this( null, entries ); 097 } 098 099 /** 100 * Creation of a new file target. 101 * @param classname the context implementation class 102 * @param entries the set of entry descriptors 103 */ 104 public ContextDirective( final String classname, final PartReference[] entries ) 105 { 106 m_classname = classname; 107 if( entries != null ) 108 { 109 for( int i=0; i<entries.length; i++ ) 110 { 111 PartReference ref = entries[i]; 112 if( null == ref ) 113 { 114 throw new NullPointerException( "entry" ); 115 } 116 } 117 m_entries = entries; 118 } 119 else 120 { 121 m_entries = EMPTY_REFS; 122 } 123 } 124 125 //-------------------------------------------------------------------------- 126 // implementation 127 //-------------------------------------------------------------------------- 128 129 /** 130 * Return the classname of the context implementation to use. 131 * @return the classname 132 */ 133 public String getClassname() 134 { 135 return m_classname; 136 } 137 138 /** 139 * Return the set of entry directives. 140 * @return the entries 141 */ 142 public PartReference[] getDirectives() 143 { 144 return m_entries; 145 } 146 147 /** 148 * Return part reference defining the value for the requested entry. 149 * @param key the context entry key 150 * @return the part reference corresponding to the supplied key or null if the 151 * key is unknown 152 */ 153 public PartReference getPartReference( String key ) 154 { 155 for( int i = 0; i < m_entries.length; i++ ) 156 { 157 PartReference entry = m_entries[ i ]; 158 if( entry.getKey().equals( key ) ) 159 { 160 return entry; 161 } 162 } 163 return null; 164 } 165 166 /** 167 * Return part defining the value for the requested entry. 168 * @param key the context entry key 169 * @return the part defintion corresponding to the supplied key or null if the 170 * key is unknown 171 */ 172 public Directive getPartDirective( String key ) 173 { 174 PartReference ref = getPartReference( key ); 175 if( null != ref ) 176 { 177 return ref.getDirective(); 178 } 179 else 180 { 181 return null; 182 } 183 } 184 185 /** 186 * Test if the supplied object is equal to this object. 187 * @param other the object to compare with this instance 188 * @return TRUE if the supplied object is equal to this object 189 */ 190 public boolean equals( Object other ) 191 { 192 if( !super.equals( other ) ) 193 { 194 return false; 195 } 196 else if( !( other instanceof ContextDirective ) ) 197 { 198 return false; 199 } 200 else 201 { 202 ContextDirective context = (ContextDirective) other; 203 if( !equals( m_classname, context.m_classname ) ) 204 { 205 return false; 206 } 207 else 208 { 209 return Arrays.equals( m_entries, context.m_entries ); 210 } 211 } 212 } 213 214 /** 215 * Return the hashcode for the instance. 216 * @return the instance hashcode 217 */ 218 public int hashCode() 219 { 220 int hash = super.hashCode(); 221 hash ^= hashValue( m_classname ); 222 hash ^= hashArray( m_entries ); 223 return hash; 224 } 225 }